package com.wangzhenyu.common.netcore.networking.http.core;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.wangzhenyu.common.netcore.networking.http.annotations.WithHiResponse;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

public final class HiConverterFactory extends Converter.Factory {

    public static HiConverterFactory create() {
        return create(new Gson());
    }

    public static HiConverterFactory create(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
        return new HiConverterFactory(gson);
    }

    private final Gson gson;

    private HiConverterFactory(Gson gson) {
        this.gson = gson;
    }

    //处理返回的ResponseBody，转化为需要的HiResponse<T>
    //返回一个处理网络请求响应（Response）的body的Converter实例，如果不能处理这些类型(type)和注解，返回null
    //这个Converter会把 ResponseBody 转化成 ?，这个ResponseBody是来自okhttp的
    //例如使用GsonConverter，？代表某个java对象类型
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {

        for (Annotation annotation : annotations) {
            if (annotation instanceof WithHiResponse && ((WithHiResponse) annotation).value()) {
                TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
                return new HiResponseBodyConverter<>(gson, adapter);
            }
        }
        //返回null表示没匹配上
        return null;
    }

    //将传入的数据变为RequestBody
    //返回一个处理网络请求（Request）的body的Converter实例，如果不能处理这些类型(type)和注解，返回null
    //这个Converter会把 ？转化成 RequestBody，这个RequestBody是来自okhttp的
    //这个Converter主要处理@Body、 @Part、@PartMap类型的注解
    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new HiRequestBodyConverter<>(gson, adapter);
    }
}